package network;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import coreAlgorithm.command.Command;
import coreAlgorithm.command.PingCommand;
import coreAlgorithm.command.PingResponse;
import coreAlgorithm.command.Response;
import exceptions.SubscriberNotFoundException;

public class SimulatedInternet implements INetwork {
	Collection<Subscriber> subscribers;
	int latestAddress;

	// @Override
	// public boolean ping(Address address) {
	// for (Iterator<Subscriber> iter = subscribers.iterator(); iter.hasNext();)
	// {
	// Subscriber subscriber = iter.next();
	// if (subscriber.getAddress().equals(address)) {
	// return subscriber.getNode().receive(senderNodeTriple, cmd);
	// }
	// }
	// return false;
	// }

	public SimulatedInternet() {
		super();
		subscribers = new ArrayList<Subscriber>();
		latestAddress = 0;
	}

	public Address logon(Subscriber sub) {
		Address newAddress = new Address(new Integer(latestAddress++).toString());
		sub.setAddress(newAddress);
		subscribers.add(sub);
		return newAddress;
	}

	public void logoff(Subscriber sub) {
		logoff(sub.getAddress());
	}

	public void logoff(Address address) {
		subscribers.remove(findSubscriber(address));
		
	}

	private Subscriber findSubscriber(Address address) {
		for (Iterator<Subscriber> iter = subscribers.iterator(); iter.hasNext();) {
			Subscriber subscriber = iter.next();
			if (subscriber.getAddress().equals(address)) {
				return subscriber;
			}
		}
		throw new SubscriberNotFoundException("Subscriber with such an Address wasn't found!");
	}

	@Override
	public Response sendCommand(Address receiverAddress, Command cmd) {
		Subscriber receiverSub;
		try {
			receiverSub = findSubscriber(receiverAddress);

		} catch (SubscriberNotFoundException e) {
			if (cmd instanceof PingCommand) {
				return new PingResponse(false);
			} else
				throw e;
		}
		// The internet is responsible to clone the command, so there are no
		// dependencies between sender and receiver - just like in the real internet...
		Response resp = receiverSub.getNode().receiveCommand(cmd.clone());
		return resp.clone();
	}

}
